package hotel.controller.order;

import javafx.fxml.FXML;

import javafx.scene.control.Button;

import javafx.scene.control.TextField;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import hotel.common.Comm;
import hotel.common.MsgBox;
import hotel.dao.HotelDao;
import hotel.modal.Customer;
import hotel.modal.Order;
import hotel.modal.Room;
import hotel.modal.RoomRent;
import hotel.modal.User;
import javafx.event.ActionEvent;
import javafx.scene.control.TitledPane;
import javafx.stage.Stage;
import javafx.scene.control.Label;

public class CheckOutController {
	@FXML
	private TitledPane roomPane;
	@FXML
	private Label durationLbl;
	@FXML
	private Label roomTypeLbl;
	@FXML
	private Label priceLbl;
	@FXML
	private Label startTimeLbl;
	@FXML
	private TitledPane custPane;
	@FXML
	private Label discountLbl;
	@FXML
	private Label creditLbl;
	@FXML
	private Label nameLbl;
	@FXML
	private Label genderLbl;
	@FXML
	private Label certIdLbl;
	@FXML
	private Label phoneLbl;
	@FXML
	private Label custTypeLbl;
	@FXML
	private TitledPane orderPane;
	@FXML
	private TextField otherField;
	@FXML
	private Label basicLbl;
	@FXML
	private TextField receivedField;
	@FXML
	private Label depositLbl;
	@FXML
	private Label discountsLbl;
	@FXML
	private TextField changeField;
	@FXML
	private Label receiveLbl;
	@FXML
	private Label totalLbl;
	@FXML
	private TextField realTotalField;
	@FXML
	private Button btnCancel;
	@FXML
	private Button btnOk;
	
	protected Order order;
	protected RoomRent roomRent;
	protected Customer customer;
	protected Room room; 
	protected User user;
	
	
	@FXML
	public void initialize() {
		initComponent();
	}
	
	private void initComponent() {
		otherField.setEditable(true);
		realTotalField.setEditable(true);
		receivedField.setEditable(true);
		changeField.setEditable(false);
		
		otherField.setTextFormatter(Comm.getDecimalFormatter());
		realTotalField.setTextFormatter(Comm.getDecimalFormatter());
		receivedField.setTextFormatter(Comm.getDecimalFormatter());
		changeField.setTextFormatter(Comm.getDecimalFormatter());
		
		otherField.textProperty().addListener((observable, oldValue, newValue) -> {
			calcRealTotal();
		});
		
		realTotalField.textProperty().addListener((observable, oldValue, newValue) -> {
			calcReceive();
		});
		
		receivedField.textProperty().addListener((observable, oldValue, newValue) -> {
			double receive = Double.valueOf(receiveLbl.getText());
			double change = Double.valueOf(receivedField.getText()) - receive;
			changeField.setText(String.format("%.2f", change));
		});
	}

	// Event Listener on Button[#btnCancel].onAction
	@FXML
	public void onBtnCancelAction(ActionEvent event) {
		closeWindow();
	}
	
	// Event Listener on Button[#btnOk].onAction
	@FXML
	public void onBtnOkAction(ActionEvent event) {
		if(room == null || roomRent == null || customer == null) {
			MsgBox.showErrorDialog("错误", null, "结账信息获取错误，请稍后再试！");
			return;
		}
		
		order = new Order();
		order.setPreOrderId(roomRent.getPreOrderId());
		order.setBasicCost(Double.valueOf(basicLbl.getText()));
		order.setOtherCost(Double.valueOf(otherField.getText()));
		order.setTotalCost(Double.valueOf(totalLbl.getText()));
		order.setRealCharge(Double.valueOf(realTotalField.getText()));
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		order.setCreateTime(now.format(formatter));
		order.setValid(true);
		order.setModified(true);
		
		customer.setCredit(customer.getCredit() + order.getRealCharge());
		customer.setModified(true);
		room.setStatus(4); 	// 入住后设置为脏房
		room.setModified(true);
		roomRent.setLeaveTime(now.format(formatter));
		room.setModified(true);
		
		hideWindow();
		if(HotelDao.add(order)) {		// 生成结账单
			HotelDao.update(roomRent);	// 更新入住信息
			HotelDao.update(room);		// 更新房间信息
			HotelDao.update(customer);	// 更新客户积分信息
			MsgBox.showInformationDialog("提示", null, String.format("客户(%d)成功为房间(%s)结账！", 
					customer.getCustomerNo(), room.getRoomNo()));
			
			closeWindow();
		}else {
			MsgBox.showErrorDialog("错误", null, "结账失败！");
		}
		
		closeWindow();
		
		
	}
	
	private void hideWindow() {
		Stage stage = (Stage)btnCancel.getScene().getWindow();
		stage.hide();
	}
	
	private void closeWindow() {
		Stage stage = (Stage)btnCancel.getScene().getWindow();
		stage.close();
	}
	
	protected void calcRealTotal() {
		double basic = Double.valueOf(basicLbl.getText());
		double other = Double.valueOf(otherField.getText());
		double discounts = Double.valueOf(discountsLbl.getText());
		double realTotal = basic + other - discounts;					// 实际消费=开房费用+其他费用-优惠金额
		totalLbl.setText(String.format("%.2f", basic+other));
		realTotalField.setText(String.format("%.2f", realTotal));
		calcReceive();
	}
	
	protected void calcReceive() {
		double realTotal = Double.valueOf(realTotalField.getText());
		double receive = realTotal - roomRent.getDeposit();				// 应加收金额=实际消费-押金
		receiveLbl.setText(String.format("%.2f", receive));
		if(receive > 0) {
			receivedField.setText(String.format("%.2f", receive));
			changeField.setText("0.00");
		}else {
			receivedField.setText("0.00");
			changeField.setText(String.format("%.2f", Math.abs(receive)));
		}
	}
	
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
	public Room getRoom() {
		return room;
	}

	public void setRoom(Room room) {
		this.room = room;
		if(this.room == null) return ;
		room.setModified(false);
		roomRent = HotelDao.getRoomRentFromRoom(room.getRoomNo());
		if(roomRent == null) return ;
		customer = HotelDao.getCustomer(roomRent.getCustomerNo());
		if(customer == null) return;
		
		roomPane.setText(String.format("入住房间资料（房间号：%s）", roomRent.getRoomNo()));
		String roomType = room.getTypeName();
		if(room.isHourRoom()) roomType += "(钟点房)";
		roomTypeLbl.setText(roomType);
		String price = String.format("%.2f元/%s", room.getPrice(), room.isHourRoom()?"小时":"天");
		priceLbl.setText(price);
		durationLbl.setText(String.format("%d天", roomRent.getDuration()));
		startTimeLbl.setText(roomRent.getStartTime());
		nameLbl.setText(customer.getName());
		genderLbl.setText(customer.getGender());
		certIdLbl.setText(customer.getCertId());
		phoneLbl.setText(customer.getPhone());
		custTypeLbl.setText(customer.getTypeName());
		discountLbl.setText(String.format("%.2f", customer.getDiscountRate()));
		creditLbl.setText(String.format("%.2f", customer.getCredit()));
		roomPane.setText(String.format("入住房间资料（房间号：%s）", room.getRoomNo()));
		custPane.setText(String.format("客户资料（客户编号：%d）", customer.getCustomerNo()));
		
		double basic = room.getPrice() * roomRent.getDuration(); 		// 开房费用=房间单价*时间
		double other = 0.00;									 		// 其他费用，由操作员输入，默认为0
		double discounts = basic * (1.0 - customer.getDiscountRate());	// 优惠金额 =开房费用*折扣
		basicLbl.setText(String.format("%.2f", basic));
		otherField.setText(String.format("%.2f", other));
		discountsLbl.setText(String.format("%.2f", discounts)); 
		depositLbl.setText(String.format("%.2f", roomRent.getDeposit()));
		calcRealTotal();
	}
}
